﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TLang.Ast
{
    public class Argument
    {
        public readonly List<Node> Elements;
        public readonly List<Node> Positional = new List<Node>();
        public readonly Map<String, Node> Keywords = new Map<string, Node>();


        public Argument(List<Node> elements)
        {
            bool hasName = false;
            bool hasKeyword = false;

            for (int i = 0; i < elements.Count; i++)
            {
                if (elements[i] is KeywordNode)
                {
                    hasKeyword = true;
                    i++;
                }
                else
                {
                    hasName = true;
                }
            }

            if (hasName && hasKeyword)
            {
                throw Util.GeneralError(elements[0], "mix positional and keyword arguments not allowed: " + elements);
            }


            this.Elements = elements;

            for (int i = 0; i < elements.Count; i++)
            {
                Node key = elements[i];
                if (key is KeywordNode)
                {
                    String id = ((KeywordNode)key).Id;
                    Positional.Add(((KeywordNode)key).AsName());

                    if (i >= elements.Count - 1)
                    {
                        throw Util.GeneralError(key, "missing value for keyword: " + key);
                    }
                    else
                    {
                        Node value = elements[i + 1];
                        if (value is KeywordNode)
                        {
                            throw Util.GeneralError(value, "keywords can't be used as values: " + value);
                        }
                        else
                        {
                            if (Keywords.ContainsKey(id))
                            {
                                throw Util.GeneralError(key, "duplicated keyword: " + key);
                            }
                            Keywords.Put(id, value);
                            i++;
                        }
                    }
                }
                else
                {
                    Positional.Add(key);
                }
            }
        }


        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();
            bool first = true;
            foreach (Node e in Elements)
            {
                if (!first)
                {
                    sb.Append(" ");
                }
                sb.Append(e);
                first = false;
            }
            return sb.ToString();
        }
    }
}
